//
//  Block.cpp
//  app-ios gl
//
//  Created by MeherTj on 2022/1/20.
//  Copyright © 2022 lover. All rights reserved.
//

#include "VBlock.hpp"
#include "Ctrl.hpp"

VBlockCache * VBlockCache::Get()
{
	static VBlockCache * c = nullptr;
	if(!c) c = new VBlockCache;
	return c;
}

VBlockCache::VBlockCache()
{
	for(int i = 1; i <= GBlockColorCount; ++i)
	{
		m_textures.push_back(TexturesCache::Get()->getTexture(GetPath("block%d", i)));
	}
}

auto VBlockCache::getTexture(int c) -> SharedTexture {
	if(c <= 0 || c > GBlockColorCount) return nullptr;
	return m_textures[c-1];
}

void VBlock::loadView()
{
	auto sr = std::make_shared<Sprite>();
	this->addNode(sr);
	sr->setAnchor({0.5f, 0.5f});

	m_main = sr.get();
	Size2 size = { 116.f, 116.f };
	m_main->setContentSize(size);
	m_view_size = { 80.f, 80.f };
}

void VBlock::setBlockColorCode(int c)
{
	if(c == 0) m_main->setVisible(false);
	else {
		m_main->setVisible(true);
		if(m_color != c)
		{
			m_main->setTexture(VBlockCache::Get()->getTexture(c));
			m_color = c;
		}
	}
}

void VTetrisBlocks::loadView()
{
	for(int i = 0; i < GPotsMaxCount; ++i) {
		auto b = std::make_shared<VBlock>();
		this->addNode(b);
		m_subs[i] = b.get();
	}
	m_info.type = TetrisTypeNone;
}

void VTetrisBlocks::setStatus(TetrisInfo info, bool centered) {
	if(info.color != m_info.color) {
		for(auto i : m_subs) i->setBlockColorCode(info.color);
	}
	auto size = m_subs[0]->getViewSize();
	if(info.type != m_info.type || info.direct != m_info.direct || m_is_centered != centered) {
		float min_x = 0;
		float max_x = 0;
		float min_y = 0;
		float max_y = 0;
		auto poses = TetrisConfig::GetSubPoses(info.type, info.direct, {0, 0});
		for(int i = 0; i < poses.size(); ++i)
		{
			auto b = m_subs[i];
			auto & p = poses[i];

			auto x = size.w * p.x;
			auto y = size.h * p.y;

			b->setPosition({x, y});
			b->setVisible(true);

			if(x > max_x) max_x = x;
			else if(x < min_x) min_x = x;
			if(y > max_y) max_y = y;
			else if(y < min_y) min_y = y;
		}
		for(auto i = poses.size(); i < GPotsMaxCount; ++i) {
			m_subs[i]->setVisible(false);
		}
		if(centered)
		{
			Vec2 shift = { (min_x + max_x) * 0.5f, (min_y + max_y)*0.5f };
			for(auto b : m_subs) {
				b->setPosition(b->getPosition() - shift);
			}
		}

	}
	m_is_centered = centered;
	m_info = info;
}
